/*   
 * Copyright 2010 Rob Schoening
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.fortasoft.hatfield.util.expression;

import java.util.concurrent.ConcurrentHashMap;

import org.fortasoft.hatfield.util.exception.HatfieldException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class ExpressionEngineFactory {
    public static final String JEXL_PROVIDER = "org.fortasoft.hatfield.util.expression.JexlExpressionEngineFactory";
    public static final String SPRING_PROVIDER = "org.fortasoft.hatfield.util.expression.SpringExpressionEngineFactory";
    public static final String MVEL_PROVIDER = "org.fortasoft.hatfield.util.expression.MvelExpressionEngineFactory";
    public static final String GROOVY_PROVIDER = "org.fortasoft.hatfield.util.expression.GroovyExpressionEngineFactory";


    public abstract ExpressionEngine getExpressionEngine();

    static Logger log = LoggerFactory.getLogger(ExpressionEngineFactory.class);
    public static ConcurrentHashMap<String, ExpressionEngineFactory> factories = new ConcurrentHashMap<String, ExpressionEngineFactory>();


    public static ExpressionEngine createExpressionEngine(final String shortName) {
        try {

            String className = shortName.toLowerCase();

            ExpressionEngineFactory f = factories.get(shortName.toLowerCase());
            if (f != null) {

                return f.getExpressionEngine();
            }
            className = className.substring(0, 1).toUpperCase()
                    + className.substring(1);
            className = ExpressionEngineFactory.class.getPackage().getName()
                    + "." + shortName.substring(0, 1).toUpperCase()
                    + shortName.toLowerCase().substring(1)
                    + "ExpressionEngineFactory";
            log.info("Creating expression factory for '{}': {}", shortName,
                    className);
            f = (ExpressionEngineFactory) Class.forName(className)
                    .newInstance();
            factories.put(shortName.toLowerCase(), f);
            return f.getExpressionEngine();
        } catch (ClassNotFoundException e) {
            throw new HatfieldException(e);
        } catch (InstantiationException e) {
            throw new HatfieldException(e);
        } catch (IllegalAccessException e) {
            throw new HatfieldException(e);
        }
    }
}
